package com.fengwk.support.util;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.ReentrantLock;

import com.fengwk.support.exception.BaseException;
import com.fengwk.support.function.Void;
import com.fengwk.support.thread.CountDownLatchWork;
import com.fengwk.support.thread.CyclicBarrierWork;

public class ThreadUtils {
	
	private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool();
	
	private ThreadUtils() {
		throw new BaseException("can not instance " + getClass());
	}
	
	/**
	 * 开始执行一个新的线程
	 * 
	 * @param command Runnable
	 * @return
	 */
	public static Thread start(Runnable command) {
		Thread t = new Thread(command);
		t.start();
		return t;
	}
	
	/**
	 * 开始执行一个新的线程{@link CompletableFuture}
	 * 
	 * @param task Callable
	 * @return
	 */
	@Deprecated
	public static <V> Thread start(Callable<V> task) {
		FutureTask<V> fTask = new FutureTask<V>(task);
		Thread t = new Thread(fTask);
		t.start();
		return t;
	}
	
	/**
	 * 使用线程池执行一个线程
	 * 
	 * @param command Runnable
	 */
	public static void execute(Runnable command) {
		EXECUTOR_SERVICE.execute(command);
	}
	
	/**
	 * 使用线程池执行一个线程{@link CompletableFuture}
	 * 
	 * @param task Callable
	 * @return
	 */
	@Deprecated
	public static <V> Future<V> submit(Callable<V> task) {
		return EXECUTOR_SERVICE.submit(task);
	}
	
	/**
	 * 阻塞当前线程,任务线程的协同执行,直至任务线程执行完毕
	 * 
	 * @param works 任务线程集
	 * @throws InterruptedException
	 */
	public static void runCountDownLatchWork(Void.Params0...workFuns) throws InterruptedException {
		if (ArrayUtils.isNotBlank(workFuns)) {
			List<CountDownLatchWork> cdlwList = new ArrayList<CountDownLatchWork>();
			for (Void.Params0 workFun: workFuns) {
				cdlwList.add(new CountDownLatchWork(workFun));
				runCountDownLatchWork(CollectionUtils.toArray(cdlwList, CountDownLatchWork.class));
			}
		}
	}
	
	/**
	 * 阻塞当前线程,任务线程的协同执行,直至任务线程执行完毕
	 * 
	 * @param workList 任务线程集
	 * @throws InterruptedException
	 */
	public static void runCountDownLatchWork(List<Void.Params0> workFunList) throws InterruptedException {
		runCountDownLatchWork(CollectionUtils.toArray(workFunList, Void.Params0.class));
	}
	
	/**
	 * 阻塞当前线程,任务线程的协同执行,直至任务线程执行完毕
	 * 
	 * @param cdlws CountDownLatch集
	 * @throws InterruptedException
	 */
	private static void runCountDownLatchWork(CountDownLatchWork...cdlws) throws InterruptedException {
		CountDownLatch cdl = new CountDownLatch(cdlws.length);
		for(CountDownLatchWork cdlw: cdlws) {
			cdlw.setCdl(cdl);
			execute(cdlw);
		}
		cdl.await(); 
	}
	
	/**
	 * 阻塞当前线程,任务线程的协同执行,可分开任务线程的after与before
	 * 
	 * @param cbList
	 */
	public static void runCyclicBarrierWork(List<CyclicBarrierWork> cbList) {
		runCyclicBarrierWork(CollectionUtils.toArray(cbList, CyclicBarrierWork.class));
	}
	
	/**
	 * 阻塞当前线程,任务线程的协同执行,可分开任务线程的after与before
	 * 
	 * @param cbws
	 */
	public static void runCyclicBarrierWork(CyclicBarrierWork...cbws) {
		CyclicBarrier cb  = new CyclicBarrier(cbws.length);
		for(CyclicBarrierWork cbw: cbws) {
			cbw.setCb(cb);
			execute(cbw);
		}
	}
	
	/**
	 * 解锁操作,注意将解锁操作置于finally代码块中使用
	 * 
	 * @param lock
	 */
	public static void unlock(ReentrantLock lock) {
		if (lock != null && lock.isHeldByCurrentThread())
			lock.unlock();
	}

}
